package org.elanfox.intellicommunity.intellicommunityadmin.controller;

import org.elanfox.intellicommunity.biz.entity.auth.SystemManager;
import org.elanfox.intellicommunity.biz.entity.auth.SystemMenu;
import org.elanfox.intellicommunity.biz.entity.auth.SystemRole;
import org.elanfox.intellicommunity.biz.service.core.auth.SystemService;
import org.elanfox.intellicommunity.common.base.ApiResult;
import org.elanfox.intellicommunity.common.base.ResultCodeEnum;
import org.elanfox.intellicommunity.common.resource.StaticResourceService;
import org.elanfox.intellicommunity.intellicommunityadmin.annotation.OperatorId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author guomw
 * @date 2018/9/17
 */
@Controller
@RequestMapping("sys")
@PreAuthorize("hasAnyRole('ADMIN')")
public class SystemController {
    @Autowired
    private SystemService systemService;
    @Autowired
    private StaticResourceService resourceService;

    /**
     * 菜单管理页面
     *
     * @return
     */
    @RequestMapping("/menus")
    public String menusPage() {
        return "system/menus";
    }

    /**
     * 分组管理页面
     *
     * @return
     */
    @RequestMapping("/groups")
    public String groupsPage() {
        return "system/groups";
    }

    /**
     * 角色管理页面
     *
     * @return
     */
    @RequestMapping("/roles")
    public String rolesPage() {
        return "system/roles";
    }

    /**
     * 账户管理页面
     *
     * @return
     */
    @RequestMapping("/manager")
    public String managerPage() {
        return "system/manager";
    }

    /**
     * 保存菜单
     *
     * @param itemParentCode 父节点ID
     * @param itemCode       当前菜单ID
     * @param itemName       菜单名称
     * @param itemSort       菜单排序
     * @param itemPath       菜单路径
     * @param itemIconCls    菜单样式
     * @return
     */
    @RequestMapping(value = "/ajax/save", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult save(@RequestParam int itemParentCode,
                          @RequestParam int itemCode,
                          @RequestParam String itemName,
                          @RequestParam(required = false, defaultValue = "0") int itemSort,
                          @RequestParam String itemPath,
                          @RequestParam(required = false, defaultValue = "") String itemIconCls,
                          @RequestParam(required = false, defaultValue = "false") boolean itemFunction) {
        /**
         * todo:安全授权认证逻辑
         */

        SystemMenu menu = new SystemMenu();
        if (itemCode > 0) {
            menu = systemService.findByItemCode(itemCode);
        } else {
            menu.setCreateTime(LocalDateTime.now());
            menu.setItemParentCode(itemParentCode);
            menu.setItemEnable(true);
        }
        menu.setItemName(itemName);
        menu.setItemSort(itemSort);
        if (itemPath.indexOf("/") != 0 && !itemName.contains("http://")) {
            itemPath = "/" + itemPath;
        }
        menu.setItemPath(itemPath);
        menu.setItemIconCls(itemIconCls);
        menu.setItemFunction(itemFunction);
        try {
            systemService.save(menu);
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        } catch (Exception ex) {
            return ApiResult.resultWith(ResultCodeEnum.ERROR, "保存失败");
        }

    }

    /**
     * 左侧菜单数据
     *
     * @param operatorId
     * @return
     */
    @RequestMapping(value = "/ajax/leftlist", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult leftList(@AuthenticationPrincipal SystemManager manager) {
        List<SystemMenu> menus = systemService.findByUserId(manager.getUserId());
        if (menus != null && menus.size() > 0) {
            menus = menus.stream().filter(r -> r.isItemEnable()).collect(Collectors.toList());
        }
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, menus);
    }

    /**
     * 获取所有菜单列表
     *
     * @return
     */
    @RequestMapping(value = "/ajax/list", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult list(@OperatorId Integer operatorId) {
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, systemService.findByUserId(operatorId));
    }

    /**
     * 查看菜单信息
     *
     * @param itemCode
     * @return
     */
    @RequestMapping(value = "/ajax/details", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult details(@RequestParam Integer itemCode) {
        SystemMenu menu = systemService.findByItemCode(itemCode);
        if (menu != null) {
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        } else {
            return ApiResult.resultWith(ResultCodeEnum.NOT_AUTHORITY, "非法操作");
        }
    }

    /**
     * 更新菜单激活状态
     *
     * @param itemCode
     * @return
     */
    @RequestMapping(value = "/ajax/activate", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult activate(@RequestParam Integer itemCode) {
        if (systemService.updateEnableByItemCode(itemCode)) {
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        } else {
            return ApiResult.resultWith(ResultCodeEnum.ERROR);
        }
    }

    /**
     * 删除菜单
     *
     * @param itemCode
     * @return
     */
    @RequestMapping(value = "/ajax/delete", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult delete(@RequestParam Integer itemCode) {
        if (systemService.deleteByItemCode(itemCode)) {
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        }
        return ApiResult.resultWith(ResultCodeEnum.ERROR, "请检查菜单是否存在子菜单！");
    }

    /**
     * 获取分组列表
     *
     * @return
     */
    @RequestMapping(value = "/ajax/rolelist", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult groupList(@OperatorId Integer operatorId) {
        //TODO:此处需要判断获取当前用户ID
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, systemService.findRoleByUserId(operatorId));
    }

    /**
     * 编辑分组
     *
     * @param roleId   分组ID
     * @param roleName 分组名称
     * @return
     */
    @RequestMapping(value = "/ajax/editrole", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult editGroup(@OperatorId Integer operatorId,
                               @RequestParam Integer roleId,
                               @RequestParam String roleName) {

        SystemRole role = new SystemRole();
        if (roleId > 0) {
            role = systemService.findRoleById(roleId);
        } else {
            role.setCreateTime(LocalDateTime.now());
            role.setUserId(operatorId);
        }
        role.setRoleName(roleName);
        role.setAuthority("");
        role.setEnable(true);
        try {
            if (systemService.saveRole(role) != null) {
                return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
            }
        } catch (Exception ex) {

        }
        return ApiResult.resultWith(ResultCodeEnum.ERROR, "保存失败");
    }

    /**
     * 删除分组
     *
     * @param roleId 分组ID
     * @return
     */
    @RequestMapping(value = "/ajax/deleterole", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult deleteGroup(@OperatorId Integer operatorId,
                                 @RequestParam Integer roleId) {
        if (systemService.deleteRoleById(roleId, operatorId)) {
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        }
        return ApiResult.resultWith(ResultCodeEnum.ERROR, "您没有操作权限!");
    }

    /**
     * 设置分组权限
     *
     * @param roleId
     * @param authority
     * @return
     */
    @RequestMapping(value = "/ajax/setpower", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult setPower(@RequestParam Integer roleId,
                              @RequestParam String authority) {
        SystemRole role = systemService.findRoleById(roleId);
        if (role != null) {
            role.setAuthority(authority);
            if (systemService.saveRole(role) != null) {
                return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
            }
        }
        return ApiResult.resultWith(ResultCodeEnum.ERROR);
    }

    /**
     * 设置角色启用或禁用
     *
     * @param roleId
     * @return
     */
    @RequestMapping(value = "/ajax/setenable", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult setEnable(@RequestParam Integer roleId) {
        if (systemService.updateEnableByRoleId(roleId)) {
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        } else {
            return ApiResult.resultWith(ResultCodeEnum.ERROR);
        }
    }

    /***
     * 获取管理员列表
     * @return
     */
    @RequestMapping(value = "/ajax/managerlist", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult managerList(@OperatorId Integer operatorId) {
        return ApiResult.resultWith(ResultCodeEnum.SUCCESS, systemService.findByParentUserId(operatorId));
    }

    /**
     * 设置账户启用或禁用
     *
     * @param rootId
     * @return
     */
    @RequestMapping(value = "/ajax/setuserenable", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult setManagerEnable(@RequestParam Integer rootId) {
        if (systemService.updateManagerEnableById(rootId)) {
            return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
        } else {
            return ApiResult.resultWith(ResultCodeEnum.ERROR);
        }
    }

    /**
     * 编辑管理员信息
     *
     * @param rootId
     * @param loginName
     * @param loginPwd
     * @param roleId
     * @return
     */
    @RequestMapping(value = "/ajax/editmanager", method = RequestMethod.POST)
    @ResponseBody
    public ApiResult editManager(@OperatorId Integer operatorId,
                                 @RequestParam Integer rootId,
                                 @RequestParam String loginName,
                                 @RequestParam String loginPwd,
                                 @RequestParam Integer roleId) {
        try {
            SystemManager manager = new SystemManager();
            if (rootId > 0) {
                manager = systemService.findManagerById(rootId);
            } else {
                if (!StringUtils.isEmpty(systemService.findManagerByLoginName(loginName))) {
                    return ApiResult.resultWith(ResultCodeEnum.ERROR, "用户名已存在");
                }
                manager.setUserId(0);
                manager.setParentUserId(operatorId);
                manager.setEnable(true);
                manager.setLoginName(loginName);
                manager.setCreateTime(LocalDateTime.now());
            }
            //如果是添加管理员，且密码为空时
            if (manager.getUserId() == 0 && StringUtils.isEmpty(loginPwd)) {
                return ApiResult.resultWith(ResultCodeEnum.ERROR, "请输入账户密码");
            }

            if (!StringUtils.isEmpty(loginPwd)) {
                BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
                //loginPwd = DigestUtils.md5DigestAsHex(loginPwd.getBytes("UTF-8")).toLowerCase();
                manager.setLoginPwd(passwordEncoder.encode(loginPwd));
            }
            manager.setLastLoginTime(LocalDateTime.now());
            SystemRole role = systemService.findRoleById(roleId);
            if (role == null) {
                return ApiResult.resultWith(ResultCodeEnum.ERROR, "请重新选中所属角色");
            }
            manager.setRole(systemService.findRoleById(roleId));

            if (systemService.saveManager(manager) != null) {
                return ApiResult.resultWith(ResultCodeEnum.SUCCESS);
            }
        } catch (Exception ex) {

        }
        return ApiResult.resultWith(ResultCodeEnum.ERROR, "保存失败");
    }

}
